﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data;
using MySql.Data.MySqlClient;
using System.Windows.Forms;
using ClassLibraryCSV;

namespace Registro
{
    public class BaseDatos
    {

        string _cadconn = "";

        public DataSet LeerRegistros(string sql)
        {   // para Ejecutar consultas SELECT-FROM-WHERE que devuelve un conjunto de Registros, Ejemplo:
            // DataSet ds = bd.LeerRegistros("SELECT usuario, [nombre completo] FROM Usuarios ORDER BY usuario;");
            claseConexion cnct = new claseConexion();
            _cadconn = "server=" + cnct.ip + "; database=" + cnct.pz + "; uid=" + cnct.uzr + "; pwd=" + cnct.pz + ";";
            using (MySqlConnection cnn = new MySqlConnection(_cadconn))
            {
                cnn.Open();
                MySqlDataAdapter da = new MySqlDataAdapter(sql, cnn);
                DataSet ds = new DataSet();
                try
                {
                    da.Fill(ds);
                    return (ds);
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Instrucción SQL:  " + sql +
                        "\n\nEl DBMS ha devuelto el siguiente error:\n" + ex.Message,
                        "Error en la instrucción SQL", MessageBoxButtons.OK,
                        MessageBoxIcon.Information);
                    return null;
                }
            }
        }

        public double LeerUnNumerico(string sql)
        {
            using (MySqlConnection cnn = new MySqlConnection(_cadconn))
            {
                MySqlCommand cmd = new MySqlCommand(sql, cnn);
                try
                {
                    cnn.Open();
                    object num = cmd.ExecuteScalar();
                    cnn.Close();
                    cmd = null;
                    if (num is DBNull)
                        return 0.0;
                    else
                        return (Convert.ToDouble(num));
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Instrucción SQL:  " + sql +
                        "\n\nEl DBMS ha devuelto el siguiente error:\n" + ex.Message,
                        "Error al conectar o recuperar los datos", MessageBoxButtons.OK,
                        MessageBoxIcon.Information);
                    cmd = null;
                    return 0.0;
                }
            }
        }


        public DataRow LeerUnRegistro(string sql)
        {   // para Ejecutar consultas SELECT-FROM-WHERE que devuelvan 1 solo registro, Ejemplo:
            // DataRow dr = bd.LeerUnRegistro("SELECT * FROM Usuarios WHERE Usuario='" + textBox1.Text.Trim() + "';");
            claseConexion cnct = new claseConexion();
            _cadconn = "server=" + cnct.ip + "; database=" + cnct.bd + "; uid=" + cnct.uzr + "; pwd=" + cnct.pz + ";";
            using (MySqlConnection cnn = new MySqlConnection(_cadconn))
            {
                MySqlDataAdapter da = new MySqlDataAdapter(sql, cnn);
                DataSet ds = new DataSet();
                try
                {
                    da.Fill(ds);
                    return (ds.Tables[0].Rows[0]);
                }
                catch (Exception ex)
                {
                    //MessageBox.Show("Instrucción SQL:  " + sql +
                    //    "\n\nEl DBMS ha devuelto el siguiente error:\n" + ex.Message,
                    //    "Error al conectar o recuperar los datos", MessageBoxButtons.OK,
                    //    MessageBoxIcon.Information);
                    return null;
                }
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sql"></param>
        /// <param name="error"></param>
        /// <returns></returns>
        public DataRow LeerUnRegistro(string sql, ref string error)
        {   // para Ejecutar consultas SELECT-FROM-WHERE que devuelvan 1 solo registro, Ejemplo:
            // DataRow dr = bd.LeerUnRegistro("SELECT * FROM Usuarios WHERE Usuario='" + textBox1.Text.Trim() + "';");
            // Si hay error, este método te lo devuelve en la cadena 'error' para que puedas darle un
            // Tratamiento personalizado.
            claseConexion cnct = new claseConexion();
            _cadconn = "server=" + cnct.ip + "; database=" + cnct.bd + "; uid=" + cnct.uzr + "; pwd=" + cnct.pz + ";";
            using (MySqlConnection cnn = new MySqlConnection(_cadconn))
            {
                error = "";
                cnn.Open();
                MySqlCommand cmd = new MySqlCommand(sql, cnn);
                MySqlDataAdapter da = new MySqlDataAdapter(sql, cnn);
                DataSet ds = new DataSet();
                try
                {
                    da.Fill(ds);
                    return (ds.Tables[0].Rows[0]);
                }
                catch (Exception ex)
                {
                    error = sql + "\n\n" + ex.Message;
                    return null;
                }
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="tbl"></param>
        /// <returns></returns>
        public DataTable LeerTabla(string tbl)
        {   // para Ejecutar consultas SELECT-FROM que devuelvan 1 tabla COMPLETA, Ejemplo:
            // DataTable dt = bd.LeerTabla("Libros");
            using (MySqlConnection cnn = new MySqlConnection(_cadconn))
            {
                string sql = "SELECT * FROM " + tbl + ";";
                cnn.Open();
                MySqlDataAdapter da = new MySqlDataAdapter(sql, cnn);
                DataTable dt = new DataTable();
                try
                {
                    da.Fill(dt);
                    dt.TableName = tbl;
                    return (dt);
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Instrucción SQL:  " + sql +
                        "\n\nEl DBMS ha devuelto el siguiente error:\n" + ex.Message,
                        "Error en la instrucción SQL", MessageBoxButtons.OK,
                        MessageBoxIcon.Information);
                    return null;
                }
            }
        }

        public bool EjecutarSQL(string sql)
        {   // Método para ejecutar consultas que no sean SELECT, como: INSERT, UPDATE, DELETE y Otras.
            // Este método regresa true si la consulta se ejecutó correctamente y false si no.
            using (MySqlConnection cnn = new MySqlConnection(_cadconn))
            {
                MySqlCommand cmd = new MySqlCommand(sql, cnn);
                DataSet ds = new DataSet();
                try
                {
                    cnn.Open();
                    cmd.ExecuteNonQuery();
                    cnn.Close();
                    return true;
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Instrucción SQL:  " + sql +
                        "\n\nEl DBMS ha devuelto el siguiente error:\n" + ex.Message,
                        "Error en la instrucción SQL", MessageBoxButtons.OK,
                        MessageBoxIcon.Information);
                    cnn.Close();
                    cmd = null;
                    return false;
                }
            }
        }


        public bool InsertarRegistro(string tbl, object[] campos)
        /*********************************************************************
         Este método implementa de una manera más fácil las consultas INSERT cuando son muchos campos.
        
         Ejemplo. La instrucción siguiente:
        
         *  iSql = "INSERT INTO clientes VALUES (" + 
         *      txtNum_cliente.Text + ", '" + txtNIP.Text + "', '" + txtNombre.Text + "', ... ) ;";
          
         La puedes hacer más fácil, es decir, sin lidiar con comillas apóstrofes y signos de más, de esta manera:
         1) Primero creas un arreglo de objetos llamado datos:
        
         *  Object[] datos = { txtNum_cliente.Text.Trim(), txtNIP.Text.Trim(), txtNombre.Text.Trim(), 
         *      txtApellidos.Text.Trim(), txtCalleyNum.Text.Trim(), txtEntreCalles.Text.Trim(), 
         *      txtColonia.Text.Trim(), txtCP.Text.Trim(), txtCiudad.Text.Trim(), txtEstado.Text.Trim() };
         *  
        
         2) Y luego lo usas el método de esta manera:
       
         *  if (mybd.InsertarRegistro("clientes", datos))
         *  {
         *       MessageBox.Show("Los datos han sido guardados.", "Aviso del Sistema");
         *       HuboCambio = true;
         *  }
         *********************************************************************/
        {
            string iSql = "INSERT INTO " + tbl + " VALUES (";

            if (campos[0] is string)
                iSql = iSql + "'" + campos[0] + "'";
            else if (campos[0] is DateTime)
                iSql = iSql + fechaMySQL((DateTime)campos[0]);
            else
                iSql = iSql + campos[0];

            for (int x = 1; x < campos.Length; x++)
            {
                if (campos[x] is string)
                    iSql = iSql + ", '" + campos[x] + "'";
                else if (campos[x] is DateTime)
                    iSql = iSql + ", " + fechaMySQL((DateTime)campos[x]);
                else
                    iSql = iSql + ", " + campos[x];

            }
            iSql = iSql + ");";

            return (this.EjecutarSQL(iSql));
        }


        private string fechaMySQL(DateTime f)
        {
            string fa = f.Year + "-" + f.Month + "-" + f.Day;
            return fa;
        }

        public bool ModificarRegistro(string tbl, string[] campos, object[] datos, string key, object valkey)
        /*********************************************************************
         Este método implementa de una manera más fácil las consultas UPDATE cuando son muchos campos.
         *********************************************************************/
        {
            string iSql = "UPDATE " + tbl + " SET ";

            if (datos[0] is string)
                iSql = iSql + campos[0] + " = '" + datos[0] + "'";
            else if (datos[0] is DateTime)
                iSql = iSql + campos[0] + " = '" + fechaMySQL((DateTime)datos[0]) + "'";
            else
                iSql = iSql + campos[0] + " = " + datos[0];

            for (int x = 1; x < datos.Length; x++)
            {
                if (datos[x] is string)
                    iSql = iSql + ", " + campos[x] + " = '" + datos[x] + "'";
                else if (datos[x] is DateTime)
                    iSql = iSql + ", " + campos[x] + " = '" + fechaMySQL((DateTime)datos[x]) + "'";
                else
                    iSql = iSql + ", " + campos[x] + " = " + datos[x];
            }

            if (valkey is string)
                iSql = iSql + " WHERE " + key + "='" + valkey + "';";
            else if (valkey is DateTime)
                iSql = iSql + " WHERE " + key + "='" + fechaMySQL((DateTime)valkey) + "';";
            else
                iSql = iSql + " WHERE " + key + "=" + valkey + ";";

            return (this.EjecutarSQL(iSql));
        }
    }
}